Skip to main content

GPIO

IO口是怎么工作的呢?

up的视频讲解:

1 GPIO 原理

1.1 GPIO简介

GPIO(General Purpose Input Output)通用I/O端口, 是STM32芯片与外部设备的电气接口, 通过它可以实现 设备控制信息采集以及 与外部设备的通信

STM32F103C8T6只有 3 组 GPIO:GPIOA、GPIOB、GPIOC,每组标准 16 个引脚(编号 0~15,标注 PAx/PBx/PCx),但C8T6 是小容量封装,部分引脚未引出.

1.2 GPIO的工作模式

GPIO口的方向可分为输入和输出两个方向, 每个方向下又分为自身功能和复用功能 两类 ( GPIO 作为内置外设使用的时候,就叫做复用)

  • 输入 输入很显然由外部决定, 这里配置的意义在于给一个初始电压

    • Input floating 浮空
    • Input pull-up 上拉
    • Input-pull-down 下拉
    • Analog 模拟输入
  • 输出
    • Output push-pull 推挽
    • Output open-drain 开漏
    • Alternate function push-pull 复用推挽
    • Alternate function open-drain 复用开漏
  • 输出速度(3档)

    • 低速 2MHz
    • 中速 10MHz
    • 高速 50MHz

总结 : 输入 - 确定初始状态(3种) 模拟输入(1种) 输出 - 开漏输出/推挽输出(2种) 复用开漏/推挽(2种)

1.3 GPIO结构

这是GPIO的硬件结构框图,可以从这个框图中清晰的了解GPIO外设,各种模式,最右端的I/O引脚就是STM32芯片引出的GPIO引脚,其它的部件都位于芯片内部。

GPIO的硬件结构框图

保护二极管: IO引脚上下两边两个二极管用于防止引脚外部过高、过低的电压输入,当引脚电压高于VDD_FT时,上方的二极管导通,当引脚电压低于VSS时,下方的二极管导通,防止不正常电压引入芯片导致芯片烧毁

上拉、下拉电阻:控制引脚默认状态的电压,开启上拉的时候引脚默认电压为高电平,开启下拉的时候引脚默认电压为低电平

TTL施密特触发器:基本原理是当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;IO口信号经过触发器后,模拟信号转化为0和1的数字信号 也就是高低电平 并且是TTL电平协议 这也是为什么STM32是TTL电平协议的原因

P-MOS管和N-MOS管:信号由P-MOS管和N-MOS管,依据两个MOS管的工作方式,使得GPIO具有“推挽输出”和“开漏输出”的模式 P-MOS管高电平导通,低电平关闭,下方的N-MOS低电平导通,高电平关闭

1.4 GPIO四种输入模式

我们所用到的每一个GPIO其内部结构都是这样,分别对应着GPIO的八种模式 这里我们简单的介绍下:

浮空输入模式

  • GPIO作为输入功能的浮空输入时,电信号由外部流向内部的,从结构图的右侧往左侧看

  • 浮空输入模式下,I/O端口的电平信号直接进入输入数据寄存器。MCU直接读取I/O口电平,I/O的电平状态是不确定的,完全由外部输入决定;

浮空输入模式

上拉输入模式

  • 上拉输入和浮空输入的区别就是多了一个上拉电阻,这样GPIO在没有连接外部部件时的默认电平是高电平,其它流程和原来一样。

  • IO内部接上拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为高电平 如果I/O口输入低电平,那么引脚就为低电平,MCU读取到的就是低电平

  • 原因是:STM32的内部上拉是"弱上拉",即通过此上拉输出的电流是很弱的,所以有外部输入是, 电平由外部决定 上拉输入模式

下拉输入模式

  • 下拉输入和浮空输入的区别就是多了一个下拉电阻,这样GPIO在没有连接外部部件时的默认电平是低电平,其它流程和原来一样。

  • 内部接下拉电阻,此时如果IO口外部没有信号输入或者引脚悬空,IO口默认为低电平 如果I/O口输入高电平,那么引脚就为高电平,MCU读取到的就是高电平

下拉输入模式

模拟输入模式

  • 模拟输入模式和其它三种输入模式不同,它的外部电平信号没有流入输入数据寄存器,而是直接流入模拟输入部分。模拟输入一般是用来ADC读取和转换的。

  • 当GPIO引脚用于ADC采集电压的输入通道时,用作"模拟输入"功能,此时信号不经过施密特触发器,直接直接进入ADC模块,并且输入数据寄存器为空 ,CPU不能在输入数据寄存器上读到引脚状态

  • 当GPIO用于模拟功能时,引脚的上、下拉电阻是不起作用的,这个时候即使配置了上拉或下拉模式,也不会影响到模拟信号的输入输出

  • 除了 ADC 和 DAC 要将 IO 配置为模拟通道之外其他外设功能一律 要配置为复用功能模式

模拟输入模式

1.5 GPIO四种输出模式

开漏输出模式

  • GPIO输出时,电信号从内部流向外部,从结构图的左侧往右侧看

  • 开漏模式下, P-MOS始终断开, 只有 N-MOS 工作

  • 如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平

  • 若控制输出为1时,高电平,则P-MOS管和N-MOS管都关闭,输出指令就不会起到作用,此时I/O端口的电平就不会由输出的高电平决定,而是由I/O端口外部的上拉或者下拉决定 如果没有上拉或者下拉 IO口就处于悬空状态

  • 并且此时施密特触发器是打开的,即输入可用

开漏输出模式

为什么叫开漏输出?
  • MOS 管有栅极 (基极)、漏极 (集电极)、源极 (发射极)
  • 开漏 = 漏极对外开路(只接内部 N-MOS 管漏极,不接上拉电源)

推挽输出模式

  • 推挽模式下, P-MOSN-MOS 都受输出控制逻辑驱动

  • 如果我们控制输出为0,低电平,则P-MOS管关闭,N-MOS管导通,使输出低电平,I/O端口的电平就是低电平

  • 若控制输出为1 高电平,则P-MOS管导通N-MOS管关闭,使输出高电平,I/O端口的电平就是高电平,外部上拉和下拉的作用是控制在没有输出时IO口电平

  • 此时施密特触发器是打开的,即输入可用

推挽输出模式

复用开漏输出

  • 开漏复用输出和开漏输出的区别在于信号来源,复用的来源不是内部直接通过输出数据寄存器写的,而是由复用功能的外设决定的

  • 输出数据寄存器无效, 输出的高低电平的来源于其它外设

  • 施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态

复用开漏输出

复用推挽输出

  • 推挽复用输出和推挽输出的区别也在于信号来源,其信号来源是由复用功能相关的通信通道来控制

  • GPIO复用为其他外设,输出数据寄存器无效,输出的高低电平的来源于其它外设

  • 施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态

复用推挽输出

开漏输出和推挽输出的区别

开漏输出比推挽输出少用了一个P-MOS, 它的意义在于

  • 开漏输出只可输出低电平,要得到高电平状态需要上拉电阻才行

  • 开漏输出一般应用在I2C等需要“线与”功能的总线电路中。

  • 除此之外,还用在电平不匹配的场合,如需要输出5伏的高电平,就可以在外部接一个上拉电阻,上拉电源为5伏

2 GPIO 常用寄存器

STM32的每组GPIO都包含7个寄存器,分别是:

  • IDR - Input data register(输入数据寄存器):锁存引脚的实时电平状态, 供 CPU 读取

  • ODR - Output data register (输出数据寄存器):存储 CPU 要输出的目标电平状态

  • BSRR/BRR - Bit set/reset registers ( 置位 / 复位寄存器):原子操作置位 / 复位引脚, 避免多任务冲突

GPIO寄存器

剩下三个在GPIO的框架图里面没有标注出来

  • GPIOx_CRL - Port configuration register low(端口配置低寄存器): 用于配置第八位引脚的模式(PIN0到PIN7引脚) GPIOx_CRL
寄存器怎么看?
  • 该寄存器使用了32位, 每个引脚对应4位去配置, 所以一个寄存器对应8个引脚

  • 四位中, 低两位叫MODE, 高两位叫CNF

  • 低两位MODE的信息分别控制引脚的输入输出方向, 和输出速度

  • 高两位CNF的信息分别控制 输入/输出方向下的 四种模式

  • GPIOx_CRH - Port configuration register high (端口配置高寄存器) 该寄存器配置信息和上面的一样, 用于配置高八位引脚(PIN8到PIN15) GPIOx_CRH

3 GPIO 常用函数

3.1 GPIO配置函数

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; /*选择Pin9引脚*/

3.2 GPIO功能函数

5 按键 GPIO输入 实验

4 蜂鸣器 GPIO输出 实验